//---------------------------------------------------------------------
//  This file is part of the Background Motion solution.
// 
//  Copyright (C) Mindscape (TM).  All rights reserved.
//  http://www.mindscape.co.nz
// 
//  THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
//  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//  PARTICULAR PURPOSE.
//---------------------------------------------------------------------

using System.Configuration;
using System.IO;
using System.Reflection;
using System.Text;
using Lonwas.Highlight;

namespace Mindscape.BackgroundMotion.Website.Infrastructure
{
  public class CodeHighlighter
  {
    private string _configurationFile;
    private bool _inputIsHtmlEncoded;
    private string _numberedOutputPattern;
    private string _outputPattern;
    private bool _showLineNumbers;

    public CodeHighlighter()
    {
      InputIsHtmlEncoded = false;
      ShowLineNumbers = false;
      OutputPattern = "<pre>{0}</pre>";
      NumberedOutputPattern = string.Empty;
      ConfigurationFile = ConfigurationManager.AppSettings["CodeHighlightDefinitionsFile"];
    }

    public string ConfigurationFile
    {
      get { return _configurationFile; }
      set { _configurationFile = value; }
    }

    public bool InputIsHtmlEncoded
    {
      get { return _inputIsHtmlEncoded; }
      set { _inputIsHtmlEncoded = value; }
    }

    public string NumberedOutputPattern
    {
      get { return _numberedOutputPattern; }
      set { _numberedOutputPattern = value; }
    }

    public string OutputPattern
    {
      get { return _outputPattern; }
      set { _outputPattern = value; }
    }

    public bool ShowLineNumbers
    {
      get { return _showLineNumbers; }
      set { _showLineNumbers = value; }
    }

    public string Highlight(string input)
    {
      Highlighter highlighter = new Highlighter();
      string definition = "C#";
      if (InputIsHtmlEncoded)
      {
        input = Global.GetCleanInput(input);
      }
      else
      {
        input = input.Replace("\r\n", "\n").TrimStart(new char[] { '\n' }).TrimEnd(new char[] { '\n' });
      }
      if (ConfigurationFile != string.Empty)
      {
        highlighter.ConfigurationFile = ConfigurationFile;
      }
      input = highlighter.Highlight(input, definition);
      if (!ShowLineNumbers)
      {
        return string.Format(OutputPattern, input);
      }
      if (NumberedOutputPattern == string.Empty)
      {
        return LineNumberer.GetNumberedOutput(input);
      }
      return LineNumberer.GetNumberedOutput(input, NumberedOutputPattern);
    }
  }

  public class LineNumberer
  {
    public static string GetLineNumbers(string input)
    {
      return GetLineNumbers(input, "\n");
    }

    public static string GetLineNumbers(string input, string newLineChar)
    {
      StringBuilder builder = new StringBuilder();
      string[] textArray = input.Split(new char[] { '\n' });
      for (int i = 0; i < textArray.Length; i++)
      {
        builder.Append((i + 1) + newLineChar);
      }
      return builder.ToString();
    }

    public static string GetNumberedOutput(string input)
    {
      return GetNumberedOutput(input, string.Empty);
    }

    public static string GetNumberedOutput(string input, string outputFormat)
    {
      string format;
      if (outputFormat == string.Empty)
      {
        format = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("Lonwas.Highlight.Extensions.Resources.OutputFormat.txt")).ReadToEnd();
      }
      else
      {
        format = outputFormat;
      }
      return string.Format(format, GetLineNumbers(input), input);
    }
  }
}
